package com.util.tools.log;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;

import com.util.tools.ScreenUtil;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * UncaughtException处理类,当程序发生Uncaught异常的时候,有该类来接管程序,并记录发送错误报告.
 * <p/>
 * 需要在Application中注册，为了要在程序启动器就监控整个程序。
 */
@SuppressLint("SimpleDateFormat")
public class CrashHandler implements UncaughtExceptionHandler {
    public static final String TAG = "CrashHandler";
    // 系统默认的UncaughtException处理类
    private UncaughtExceptionHandler mDefaultHandler;
    // CrashHandler实例
    private static CrashHandler instance;
    // 程序的Context对象
    private Context mContext;
    // 用来存储设备信息和异常信息
    private Map<String, String> infos = new HashMap<String, String>();

    /**
     * 保证只有一个CrashHandler实例
     */
    private CrashHandler() {
    }

    /**
     * 获取CrashHandler实例 ,单例模式
     */
    public static CrashHandler getInstance() {
        if (instance == null)
            instance = new CrashHandler();
        return instance;
    }

    /**
     * 初始化
     */
    public void init(Context context) {
        mContext = context;
        // 获取系统默认的UncaughtException处理器
        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
        // 设置该CrashHandler为程序的默认处理器
        Thread.setDefaultUncaughtExceptionHandler(this);
    }
    public static String getProcessName(Context appContext) {
        String currentProcessName = "";
        int pid = android.os.Process.myPid();
        ActivityManager manager = (ActivityManager) appContext.getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) {
            if (processInfo.pid == pid) {
                currentProcessName = processInfo.processName;
                break;
            }
        }
        return currentProcessName;
    }
    /**
     * 当UncaughtException发生时会转入该函数来处理
     */
    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        String processName =  getProcessName(mContext);
        if (ex!=null&&mContext.getPackageName().equals(processName)) {
            saveCatchInfo(ex);
            mDefaultHandler.uncaughtException(thread, ex);
        } else {
            android.os.Process.killProcess(android.os.Process.myPid());
            System.exit(0);
        }
    }

    /**
     * 获取设备信息
     *
     * @return
     */
    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    private StringBuffer getBaseInfo() {
        StringBuffer sb = new StringBuffer();
        java.text.DateFormat df = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date curDate = new Date(System.currentTimeMillis());// 获取当前时间
        String s2 = df.format(curDate);
        sb.append("报错时间:"+s2);
        sb.append("\n\n*******应用信息********");
        try {
            PackageManager pm = mContext.getPackageManager();
            PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(),
                    PackageManager.GET_ACTIVITIES);
            if (pi != null) {
                String versionName =pi.versionName;
                String versionCode = pi.versionCode + "";
                sb.append("\nAPP版本名称(版本号)：" + versionName);
                sb.append("\nAPP版本编号：" + versionCode);
            }
        } catch (NameNotFoundException e) {
        }
        sb.append("\n\n********屏幕信息********");
        sb.append("\n显示屏参数：" + Build.DISPLAY);
        sb.append("\n屏幕分辨率：" + ScreenUtil.getScreenWidth(mContext)+"*"+ScreenUtil.getScreenHeight(mContext));
        sb.append("\n屏幕密度：" + ScreenUtil.getScreenDensity(mContext));
        sb.append("\n屏幕密度DPI：" + ScreenUtil.getScreenDensityDPI(mContext));
        sb.append("\n\n********设备信息********");
        sb.append("\n手机型号：" + Build.MODEL);
        sb.append("\n系统版本：" + Build.VERSION.RELEASE);
        sb.append("\n主板：" + Build.BOARD);
        sb.append("\n系统启动程序版本号：" + Build.BOOTLOADER);
        sb.append("\n系统定制商：" + Build.BRAND);
        sb.append("\ncpu指令集：" + Build.CPU_ABI);
        sb.append("\ncpu指令集2" + Build.CPU_ABI2);
        sb.append("\n设置参数：" + Build.DEVICE);
        sb.append("\n无线电固件版本：" + Build.getRadioVersion());
        sb.append("\n硬件识别码：" + Build.FINGERPRINT);
        sb.append("\n硬件名称：" + Build.HARDWARE);
        sb.append("\nHOST:" + Build.HOST);
        sb.append("\n修订版本列表：" + Build.ID);
        sb.append("\n硬件制造商：" + Build.MANUFACTURER);
        sb.append("\n版本：" + Build.MODEL);
        sb.append("\n手机制造商：" + Build.PRODUCT);
        sb.append("\n描述Build的标签：" + Build.TAGS);
        sb.append("\nbuilder类型：" + Build.TYPE);
        sb.append("\nUSER:" + Build.USER);
        return sb;
    }
    /**
     * 保存错误信息到文件中
     *
     * @param ex
     * @return 返回文件名称, 便于将文件传送到服务器
     */
    @SuppressLint("SdCardPath")
    private void saveCatchInfo(Throwable ex) {
        StringBuffer sb = getBaseInfo();
        Writer writer = new StringWriter();
        PrintWriter printWriter = new PrintWriter(writer);
        ex.printStackTrace(printWriter);
        Throwable cause = ex.getCause();
        while (cause != null) {
            cause.printStackTrace(printWriter);
            cause = cause.getCause();
        }
        printWriter.close();
        String result = writer.toString();
        sb.append("\n\n********错误信息********\n"+result);
        MyLog.d("异常日志：", "\n========================start=======================\n" + sb.toString() + "\n========================end=======================\n");
        if (MyLog.MYLOG_SEND_TO_DEV) {
            sendLog(ex.getMessage(), sb.toString());
        }
    }

    private void sendLog(String smsg, String lmsg) {
//        HashMap<String, String> params = new HashMap<String, String>();
//        params.put("Message", smsg);
//        params.put("FullMessage", lmsg);
//        params.put("_o","an");
//        params.put("CustomerId", mContext.getSharedPreferences(Constants.SHAREDPREFERENCESNAME, 0).getString("CustomerId", ""));
//        OkHttpUtils.post().url(Method.ERRORLOG).params(params).build().execute(new StringCallback() {
//            @Override
//            public void onError(Call call, Exception e) {
//                MyLog.i("错误信息", Method.ERRORLOG+"请求错误");
//            }
//
//            @Override
//            public void onResponse(String response) {
//                MyLog.i("日志发送", "发送成功");
//            }
//        });
    }
}
